package com.heima.app.gateway.utils;

import io.jsonwebtoken.*;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.*;

public class AppJwtUtil {

    // TOKEN的有效期一天（S）
    private static final int TOKEN_TIME_OUT = 3_600;
    // 加密KEY
    private static final String TOKEN_ENCRY_KEY = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY";
    // 最小刷新间隔(S)
    private static final int REFRESH_TIME = 300;

    // 生产ID
    public static String getToken(Long id){
        Map<String, Object> claimMaps = new HashMap<>();
        claimMaps.put("id",id);
        long currentTime = System.currentTimeMillis();
        return Jwts.builder()
                .setId(UUID.randomUUID().toString())                //设置JWT的唯一标识符（setId）为随机UUID字符串
                .setIssuedAt(new Date(currentTime))                 //签发时间为当前系统时间（setIssuedAt）
                .setSubject("system")                               //主题（setSubject）设置为"system"
                .setIssuer("heima")                                 //签发者信息（setIssuer）设置为"heima"
                .setAudience("app")                                 //接收用户（setAudience）设置为"app
                .compressWith(CompressionCodecs.GZIP)               //数据压缩方式（compressWith）选择GZIP压缩
                .signWith(SignatureAlgorithm.HS512, generalKey())   //签名算法（signWith）使用HS512，并通过generalKey()方法获取密钥
                .setExpiration(new Date(currentTime + TOKEN_TIME_OUT * 1000))  //过期时间（setExpiration）设置为当前时间加上TOKEN_TIME_OUT秒乘以1000毫秒
                .addClaims(claimMaps)                               //载荷信息claimMaps添加到JWT中（addClaims）
                .compact();                                         //调用compact()方法完成JWT构建，并返回最终的JWT字符串
    }

    /**
     * 获取token中的claims信息
     *
     * @param token
     * @return
     */
    private static Jws<Claims> getJws(String token) {
            return Jwts.parser()
                    .setSigningKey(generalKey())
                    .parseClaimsJws(token);
    }

    /**
     * 获取payload body信息
     *
     * @param token
     * @return
     */
    public static Claims getClaimsBody(String token) {
        try {
            return getJws(token).getBody();
        }catch (ExpiredJwtException e){
            return null;
        }
    }

    /**
     * 获取hearder body信息
     *
     * @param token
     * @return
     */
    public static JwsHeader getHeaderBody(String token) {
        return getJws(token).getHeader();
    }

    /**
     * 是否过期
     *
     * @param claims
     * @return -1：有效，0：有效，1：过期，2：过期
     */
    public static int verifyToken(Claims claims) {
        if(claims==null){
            return 1;
        }
        try {
            claims.getExpiration()
                    .before(new Date());
            // 需要自动刷新TOKEN
            if((claims.getExpiration().getTime()-System.currentTimeMillis())>REFRESH_TIME*1000){
                return -1;
            }else {
                return 0;
            }
        } catch (ExpiredJwtException ex) {
            return 1;
        }catch (Exception e){
            return 2;
        }
    }

    /**
     * 由字符串生成加密key
     *
     * @return
     */
    public static SecretKey generalKey() {
        byte[] encodedKey = Base64.getEncoder().encode(TOKEN_ENCRY_KEY.getBytes());
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }

    public static void main(String[] args) {
       /* Map map = new HashMap();
        map.put("id","11");*/
        System.out.println(AppJwtUtil.getToken(1102L));
        Jws<Claims> jws = AppJwtUtil.getJws("eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAADWLQQrDMAwE_6JzDJYdx3J-o9YKcSFgkAMtpX-vcshtZ4f5wms0WOHpfSGh4pKn6ObCm6OyRWd3rHOWwFhhgsYDVswhYYpIywR6PqzWjw45Lq9quEs72IjPasS925Z3v8slX2Uzh-jD7w_nL6zUgwAAAA.tf8PY37N93VkjgdfNr4uuAettoQLNBlSBDQaHrG-p4Ve3q1pS3ZjullXsAxD3d9K4CzSeS2AL6LcU6jpDMPHvA");
        Claims claims = jws.getBody();
        System.out.println(claims.get("id"));

    }

}
